package com.example.cd5160866.modelrecycleview;

import android.content.Context;
import android.support.annotation.IntDef;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import com.example.cd5160866.modelrecycleview.adapter.ModelRecyclerAdapterV3;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;


/**
 * @author cd5160866
 * @date 16/4/28
 */
public class ModelRecyclerView extends RecyclerView {
    /**
     * listView
     */
    public static final int MODEL_LIST_VIEW_VERTICAL = 1001;
    /**
     * horizontalListView
     */
    public static final int MODEL_LIST_VIEW_HORIZONTAL = 1002;
    /**
     * gridView
     */
    public static final int MODEL_GRID_VIEW_VERTICAL = 1003;
    /**
     * gridView span size
     */
    private static final int DEFAULT_GRID_SPAN = 3;

    @IntDef({MODEL_LIST_VIEW_VERTICAL, MODEL_LIST_VIEW_HORIZONTAL, MODEL_GRID_VIEW_VERTICAL})
    @Retention(RetentionPolicy.SOURCE)
    private @interface LayoutModel {
    }

    private int currentModel = MODEL_LIST_VIEW_VERTICAL;

    private ModelRecyclerAdapterV3 modelRecyclerAdapter;

    /**
     * 默认gridView行数
     */
    private int gridSpanCount = DEFAULT_GRID_SPAN;


    public ModelRecyclerView(Context context) {
        this(context, null);
    }

    public ModelRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        updateLayoutManager();
        addOnItemTouchListener(new OnRecyclerItemClickListener() {
            @Override
            public void onItemClick(RecyclerView parent, View itemView, int position) {
                if (clickListener != null) {
                    clickListener.onItemClick(parent, itemView, position);
                }
            }

            @Override
            public void onItemLongClick(RecyclerView parent, View itemView, int position) {
                if (longClickListener != null) {
                    longClickListener.onItemLongClick(parent, itemView, position);
                }
            }
        });
    }

    private void updateLayoutManager() {
        LinearLayoutManager mManager;
        switch (currentModel) {
            case MODEL_LIST_VIEW_HORIZONTAL:
                mManager = new LinearLayoutManager(getContext());
                mManager.setOrientation(LinearLayoutManager.HORIZONTAL);
                break;
            case MODEL_GRID_VIEW_VERTICAL:
                mManager = getGridLayoutManager();
                mManager.setOrientation(LinearLayoutManager.VERTICAL);
                break;
            default:
                mManager = new LinearLayoutManager(getContext());
                mManager.setOrientation(LinearLayoutManager.VERTICAL);
                break;
        }
        setLayoutManager(mManager);
    }

    private GridLayoutManager getGridLayoutManager() {
        final GridLayoutManager manager = new GridLayoutManager(getContext(), gridSpanCount);
        manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (modelRecyclerAdapter == null) {
                    return -1;
                } else {
                    if (modelRecyclerAdapter.getItemViewType(position) == ModelRecyclerAdapterV3.TYPE_DEFAULT) {
                        return 1;
                    } else {
                        return gridSpanCount;
                    }
                }
            }
        });
        return manager;
    }

    public void setModelAdapter(ModelRecyclerAdapterV3 adapter) {
        setAdapter(adapter);
    }

    @Override
    public void setAdapter(Adapter adapter) {
        if (!(adapter instanceof ModelRecyclerAdapterV3)) {
            throw new IllegalArgumentException(" please use ModelRecyclerAdapter instead");
        }
        this.modelRecyclerAdapter = (ModelRecyclerAdapterV3) adapter;
        super.setAdapter(adapter);
    }

    public void setLayoutModel(@LayoutModel int model) {
        this.currentModel = model;
        updateLayoutManager();
    }

    public int getDefultGirdSpanCount() {
        return gridSpanCount;
    }

    public void setDefultGirdSpanCount(int defaultSpanCount) {
        this.gridSpanCount = defaultSpanCount;
        updateLayoutManager();
    }

    private OnItemClickListener clickListener;

    public void setOnItemClickListener(OnItemClickListener clickListener) {
        this.clickListener = clickListener;
    }

    public void setOnItemLongClickListener(OnItemLongClickListener longClickListener) {
        this.longClickListener = longClickListener;
    }

    private OnItemLongClickListener longClickListener;

    public interface OnItemClickListener {

        /**
         * 点击监听
         *
         * @param parent   RecyclerView
         * @param itemView 该布局ItemView
         * @param position -1 代表点击header 或footer  其余代表点击用户指定item的位置
         */
        void onItemClick(RecyclerView parent, View itemView, int position);
    }

    public interface OnItemLongClickListener {

        /**
         * 长按监听
         *
         * @param parent   RecyclerView
         * @param itemView 该布局ItemView
         * @param position -1 代表点击header 或footer  其余代表点击用户指定item的位置
         */
        void onItemLongClick(RecyclerView parent, View itemView, int position);
    }


    private abstract class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
        private GestureDetectorCompat mGestureDetector;
        private RecyclerView recyclerView;

        private OnRecyclerItemClickListener() {
            this.recyclerView = ModelRecyclerView.this;
            mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelperGestureListener());
        }

        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            return mGestureDetector.onTouchEvent(e);
        }

        @Override
        public void onTouchEvent(RecyclerView rv, MotionEvent e) {
            mGestureDetector.onTouchEvent(e);
        }

        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        }

        /**
         * 这个类用于判定recycleiew的滑动状态
         */
        private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (null != child) {
                    RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                    onItemClick(recyclerView, vh.itemView, modelRecyclerAdapter.getDataPositionByLayoutPosition(vh.getLayoutPosition()));
                }
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (null != child) {
                    RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                    onItemLongClick(recyclerView, vh.itemView, modelRecyclerAdapter.getDataPositionByLayoutPosition(vh.getLayoutPosition()));
                }
            }
        }

        public abstract void onItemLongClick(RecyclerView parent, View itemView, int position);

        public abstract void onItemClick(RecyclerView parent, View itemView, int position);
    }

}